
#include "EditorWindow.h"
#include "TextureWindow.h"
#include "Editor.h"

//#include "EditorProcs.h"

#include "../leak.h"

EditorWindow::EditorWindow(string title, int size_x, int size_y, char flags) : MyBaseWindow(title, size_x, size_y, flags), cam_rot_enabled_(false),
																			right_panel_(0.0f, 0.0f, 0.5f, 0.2f, window_size_, true),
																			box_brush_button_("Box", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			grid_step_layout_(0.0f, 0.0f, 0.5f, 0.1f, window_size_, false),
																			decr_grid_step_button_("-", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			incr_grid_step_button_("+", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			selection_layout_(0.0f, 0.0f, 0.5f, 0.1f, window_size_, false),
																			clear_selection_button_("Deselect", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			delete_selection_button_("Delete", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			copy_selection_button_("Copy", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),

																			rotate_brush_layout_(0.0f, 0.0f, 0.5f, 0.1f, window_size_, false),
																			rotate_cw_button_("CW", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			rotate_ccw_button_("CCW", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			mode_layout_(0.0f, 0.0f, 0.5f, 0.1f, window_size_, false),
																			edit_mode_button_("Edit", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			select_mode_button_("Select", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),
																			tex_mode_button_("Texture", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),

																			properties_layout_(0.0f, 0.0f, 0.5f, 0.1f, window_size_, true),
																			ed_field_("value", CHARS|FLOATS),

																			input_string_("", 0.0f, 0.0f, 1.0f, 0.05f, 0.8f, window_size_, CHARS | FLOATS),
																			submit_input_btn_("-->", 0.0f, 0.0f, 0.1f, 0.1f, window_size_),

																			//file_menu_("File", 0.0, 0.0, 0.8f, window_size_),
																			file_menu_("File", 0.8f),
																			edit_menu_("Edit", 0.8f),
																			menu_layout_(false),
																			dark_back_(0.0, 0.0, 0.0, 0.0, 3, window_size_){
		//main_viewport_ = new MyGLView(-0.9f, -0.5f, 1.8f, 0.5f, window_size_);
		
		right_click.AssignFunction(this, &EditorWindow::OnRightClick);

		wheel_slot.AssignFunction(this, &EditorWindow::OnWheelRot);
		//wheel_slot.Connect(g_wheel_signal);

		viewports_.push_back(MyGLView(-0.9f, -0.5f, 1.8f, 0.5f, window_size_));
		view_names_.push_back(MyTypeMesh("Top", 0.0f, 0.0f, 1.0f, window_size_));
		viewports_.push_back(MyGLView(-0.9f, -0.5f, 1.8f, 0.5f, window_size_));
		view_names_.push_back(MyTypeMesh("Perspective", 0.0f, 0.0f, 1.0f, window_size_));
		viewports_.push_back(MyGLView(-0.9f, -0.5f, 1.8f, 0.5f, window_size_));
		view_names_.push_back(MyTypeMesh("Front", 0.0f, 0.0f, 1.0f, window_size_));
		viewports_.push_back(MyGLView(-0.9f, -0.5f, 1.8f, 0.5f, window_size_));
		view_names_.push_back(MyTypeMesh("Left", 0.0f, 0.0f, 1.0f, window_size_));

		active_cam_move_[0] = 0.0f;
		active_cam_move_[1] = 0.0f;
		active_cam_move_[2] = 0.0f;

		move_mode_ = false;

		float origin[] = { 0.0f, 0.0f, 0.0f };
		float trgt[] = { 0.0f, 0.0f, -1.0f };
		float up[] = { 0.0f, 1.0f, 0.0f };

		float origin2[] = { 0.0f, 1000.0f, 0.0f };
		float trgt2[] = { 0.0f, -1.0f, 0.0f };
		float up2[] = { 0.0f, 0.0f, 1.0f };

		float origin3[] = { 0.0f, 0.0f, 1000.0f };
		float trgt3[] = { 0.0f, 0.0f, -1.0f };
		float up3[] = { 0.0f, 1.0f, 0.0f };

		float origin4[] = { 1000.0f, 0.0f, 0.0f };
		float trgt4[] = { -1.0f, 0.0f, 0.0f };
		float up4[] = { 0.0f, 1.0f, 0.0f };

		cams_.reserve(4);

		cams_.push_back(Camera(origin2, trgt2, up2));
		cams_[ LEFT_TOP ].Orthographic(-500.0f, 500.0, 500.0f, -500.0f, 0.1f, 10000.0f);
		cams_[ LEFT_TOP ].UpdatePlanes();
		zoom_.push_back(1.0f);

		cams_.push_back(Camera(origin, trgt, up));
		cams_[ RIGHT_TOP ].Perspective(45.0f, 1.0f, 0.1f, 10000.0f);
		cams_[ RIGHT_TOP ].UpdatePlanes();
		zoom_.push_back(1.0f);

		cams_.push_back(Camera(origin3, trgt3, up3));
		cams_[ LEFT_BOTTOM ].Orthographic(-500.0f, 500.0, 500.0f, -500.0f, 0.1f, 10000.0f);
		cams_[ LEFT_BOTTOM ].UpdatePlanes();
		zoom_.push_back(1.0f);

		cams_.push_back(Camera(origin4, trgt4, up4));
		cams_[ RIGHT_BOTTOM ].Orthographic(-500.0f, 500.0, 500.0f, -500.0f, 0.1f, 10000.0f);
		cams_[ RIGHT_BOTTOM ].UpdatePlanes();
		zoom_.push_back(1.0f);

		active_cam_ = -1;
		last_active_cam_ = -1;
		maximized_view_ = -1;

		type_meshes_[ "create_brush" ] = MyTypeMesh("Create Brush:", 0.0f, 0.0f, 0.8f, window_size_);
		type_meshes_[ "grid_size" ] = MyTypeMesh("Grid Size:", 0.0f, 0.0f, 0.8f, window_size_);
		type_meshes_[ "Selection" ] = MyTypeMesh("Selection:", 0.0f, 0.0f, 0.8f, window_size_);
		type_meshes_[ "Rotate" ] = MyTypeMesh("Rotate:", 0.0f, 0.0f, 0.8f, window_size_);
		type_meshes_[ "Mode" ] = MyTypeMesh("Mode:", 0.0f, 0.0f, 0.8f, window_size_);
		type_meshes_[ "Properties" ] = MyTypeMesh("Properties:", 0.0f, 0.0f, 0.8f, window_size_);

		create_box_brush_slot_.AssignFunction(this, &EditorWindow::CreateBoxBrush);
		create_box_brush_slot_.Connect(box_brush_button_.press_signal());

		clear_selection_slot_.AssignFunction(this, &EditorWindow::ClearSelection);
		clear_selection_slot_.Connect(clear_selection_button_.press_signal());
		selection_layout_.AddElement(&clear_selection_button_);
		delete_selection_slot_.AssignFunction(this, &EditorWindow::DeleteSelected);
		delete_selection_slot_.Connect(delete_selection_button_.press_signal());
		selection_layout_.AddElement(&delete_selection_button_);
		copy_selection_slot_.AssignFunction(this, &EditorWindow::CopySelected);
		copy_selection_slot_.Connect(copy_selection_button_.press_signal());
		selection_layout_.AddElement(&copy_selection_button_);

		rotate_cw_slot_.AssignFunction(this, &EditorWindow::RotateCW);
		rotate_cw_slot_.Connect(rotate_cw_button_.press_signal());
		rotate_ccw_slot_.AssignFunction(this, &EditorWindow::RotateCCW);
		rotate_ccw_slot_.Connect(rotate_ccw_button_.press_signal());
		rotate_brush_layout_.AddElement(&rotate_cw_button_);
		rotate_brush_layout_.AddElement(&rotate_ccw_button_);

		edit_mode_slot_.AssignFunction(this, &EditorWindow::EditModeToggle);
		edit_mode_slot_.Connect(edit_mode_button_.press_signal());
		select_mode_slot_.AssignFunction(this, &EditorWindow::SelectModeOn);
		select_mode_slot_.Connect(select_mode_button_.press_signal());
		tex_mode_slot_.AssignFunction(this, &EditorWindow::TextureModeOn);
		tex_mode_slot_.Connect(tex_mode_button_.press_signal());
		mode_layout_.AddElement(&select_mode_button_);
		mode_layout_.AddElement(&edit_mode_button_);
		mode_layout_.AddElement(&tex_mode_button_);

		decr_grid_step_slot_.AssignFunction(this, &EditorWindow::DecrGridStep);
		decr_grid_step_slot_.Connect(decr_grid_step_button_.press_signal());
		incr_grid_step_slot_.AssignFunction(this, &EditorWindow::IncrGridStep);
		incr_grid_step_slot_.Connect(incr_grid_step_button_.press_signal());
		grid_step_layout_.AddElement(&decr_grid_step_button_);
		grid_step_layout_.AddElement(&incr_grid_step_button_);

		shared_ptr< MyEditBox > texture_id;
		properties_layout_.AddElement(&type_meshes_[ "Properties" ]);
		properties_layout_.AddElement(&ed_field_);

		right_panel_.AddElement(&type_meshes_[ "create_brush" ]);
		right_panel_.AddElement(&box_brush_button_);
		right_panel_.AddElement(&type_meshes_[ "grid_size" ]);
		right_panel_.AddElement(&grid_step_layout_);
		right_panel_.AddElement(&type_meshes_[ "Selection" ]);
		right_panel_.AddElement(&selection_layout_);
		right_panel_.AddElement(&type_meshes_[ "Rotate" ]);
		right_panel_.AddElement(&rotate_brush_layout_);
		right_panel_.AddElement(&type_meshes_[ "Mode" ]);
		right_panel_.AddElement(&mode_layout_);
		right_panel_.AddElement(&properties_layout_);

		input_string_.AddChar(' ');
		submit_input_slot_.AssignFunction(this, &EditorWindow::SubmitInput);
		submit_input_slot_.Connect(submit_input_btn_.press_signal());

		new_file_slot_.AssignFunction(this, &EditorWindow::NewFile);
		file_menu_.AddItem("New", new_file_slot_);

		open_file_slot_.AssignFunction(this, &EditorWindow::OpenFile);
		file_menu_.AddItem("Open", open_file_slot_);

		save_file_slot_.AssignFunction(this, &EditorWindow::SaveFile);
		file_menu_.AddItem("Save", save_file_slot_);

		undo_slot_.AssignFunction(this, &EditorWindow::Undo);
		edit_menu_.AddItem("Undo", undo_slot_);

		redo_slot_.AssignFunction(this, &EditorWindow::Redo);
		edit_menu_.AddItem("Redo", redo_slot_);

		menu_layout_.AddElement(&file_menu_);
		menu_layout_.AddElement(&edit_menu_);

		update_needed_ = true;
		OnMove(0.0f, 0.0f);

}


int EditorWindow::OnClick(float x, float y) {
		
		if(MyBaseWindow::OnClick(x, y) == -1)
		{
			return -1;
		}
		
		for(auto view = viewports_.begin(); view != viewports_.end(); view++)
		{
			if(maximized_view_ != -1 && maximized_view_ != (view - viewports_.begin()))
			{
				continue;
			}

			if((*view).Check(x, y))
			{
				last_active_cam_ = active_cam_;
				active_cam_ = view - viewports_.begin();
				move_mode_ = true;

				const float* dims = (*view).dims();
				float r_x = 2.0f*(x - dims[0])/dims[2] - 1.0f;
				float r_y = 2.0f*(y - dims[1])/dims[3] - 1.0f;

				//cout << r_x << " " << r_y << endl;

				if(!g_builder_brush->Check(r_x, r_y, cams_[ active_cam_ ], (*view)))
				{
					/*if(!g_selection_frame->Check(r_x, r_y, cams_[ active_cam_ ], (*view)))
					{
						if(g_selection_frame->CheckBrush(r_x, r_y, cams_[ active_cam_ ], (*view)))
						{

						} else
						{
							g_selection_frame->Clear();
						}
					}*/
					
					if(!g_selection_frame->Check(r_x, r_y, cams_[ active_cam_ ], (*view)))
					{
						//if(!g_selection_frame->CheckMesh(r_x, r_y, cams_[ active_cam_ ], (*view)))
						//{
							if(!g_selection_frame->CheckBrush(r_x, r_y, cams_[ active_cam_ ], (*view)))
							{
								g_selection_frame->Clear();
							}
						//}
					} else
					{
						//g_selection_frame->CheckBrush(r_x, r_y, cams_[ active_cam_ ], (*view));
					}
				}

				break;
			} else
			{
				//if(view == viewports_.end() - 1)
				//{
				//	last_active_cam_ = active_cam_;
				//	active_cam_ = -1;
				//}
			}
		}
		

		right_panel_.Check(x, y);

		input_string_.Check(x, y);

		submit_input_btn_.Check(x, y);

		menu_layout_.Check(x, y);

		return 0;
}

int EditorWindow::OnRightClick(float x, float y) {

	for(auto view = viewports_.begin(); view != viewports_.end(); view++)
	{
		if(maximized_view_ != -1 && maximized_view_ != (view - viewports_.begin()))
		{
			continue;
		}

		if((*view).Check(x, y))
		{
			last_active_cam_ = active_cam_;
			active_cam_ = view - viewports_.begin();
			move_mode_ = false;
			break;
		} else
		{
			if(view == viewports_.end() - 1)
			{
				last_active_cam_ = active_cam_;
				active_cam_ = -1;
			}
		}
	}

	input_string_.Check(x, y);

	return 0;
}

int EditorWindow::OnMove(float dx, float dy) {
		if(MyBaseWindow::OnMove(dx, dy) == -1)
		{
			return -1;
		}

		if(update_needed_)
		{

		if(maximized_view_ == -1)
		{
		viewports_[LEFT_TOP].Resize(	-1.0f + 17.0f/window_size_[0], 
										(17.0f + 36.0f - 64.0f)/window_size_[1], 
										1.0f - (32.0f + 200.0f - 8.0f)/window_size_[0], 
										1.0f - (32.0f + 36.0f + 32.0f)/window_size_[1], 
										window_size_);

		view_names_[LEFT_TOP].Move(-1.0f + 17.0f/window_size_[0],
									(17.0f + 24.0f - 64.0f + 32.0f)/window_size_[1], 
									window_size_);

		viewports_[RIGHT_TOP].Resize(	0.0f + (8.0f - 200.0f)/window_size_[0], 
										(17.0f + 36.0f - 64.0f)/window_size_[1], 
										1.0f - (32.0f + 200.0f - 8.0f)/window_size_[0], 
										1.0f - (32.0f + 36.0f + 32.0f)/window_size_[1], 
										window_size_);

		viewports_[LEFT_BOTTOM].Resize(	-1.0f + 17.0f/window_size_[0], 
										-1.0f + (17.0f + 48.0f + 8.0f)/window_size_[1], 
										1.0f - (32.0f + 200.0f - 8.0f)/window_size_[0], 
										1.0f - (32.0f + 36.0f + 32.0f)/window_size_[1], 
										window_size_);
		
		viewports_[RIGHT_BOTTOM].Resize(	0.0f + (8.0f - 200.0f)/window_size_[0], 
											-1.0f + (17.0f + 48.0f + 8.0f)/window_size_[1], 
											1.0f - (32.0f + 200.0f - 8.0f)/window_size_[0], 
											1.0f - (32.0f + 36.0f + 32.0f)/window_size_[1], 
											window_size_);
		} else
		{
			viewports_[ maximized_view_ ].Resize(	-1.0f + 17.0f/window_size_[0], 
													-1.0f + (17.0f + 48.0f + 8.0f)/window_size_[1], 
													2.0f - 2.0f*(32.0f + 200.0f - 8.0f - 8.0f)/window_size_[0], 
													2.0f - 2.0f*(32.0f + 36.0f + 32.0f - 8.0f)/window_size_[1], 
													window_size_);
		}

		for(unsigned int i = 0; i < view_names_.size(); i++)
		{
			view_names_[i].Move(	viewports_[i].dims()[0] + 16.0f/window_size_[0],
									viewports_[i].dims()[1] + 32.0f/window_size_[1],
									window_size_);
		}

		
		right_panel_.Resize(	1.0f - 400.0f/window_size_[0],
								1.0f - 800.0f/window_size_[1],
								(400.0f - 17.0f)/window_size_[0], 
								(500.0f + 200.0f)/window_size_[1],
								window_size_);

		input_string_.Resize(	-1.0f + 16.0f/window_size_[0],
								-1.0f + 16.0f/window_size_[1],
								0.7f + 0.0f/window_size_[0], 
								(48.0f)/window_size_[1],
								window_size_);

		submit_input_btn_.Resize(	-1.0f + 0.7f + 16.0f/window_size_[0],
									-1.0f + 16.0f/window_size_[1],
									72.0f/window_size_[0], 
									(48.0f)/window_size_[1],
									window_size_);


		}



		float rot_vec[] = { 0.0f, 0.0f, 0.0f };

		const float* v = nullptr;
		const int* v_px = nullptr;
		//float ff;

		if(active_cam_ != -1)
		{
		if(!move_mode_)
		{
			switch(active_cam_)
			{
			case LEFT_TOP:
			case LEFT_BOTTOM:
			case RIGHT_BOTTOM:

				v = viewports_[ active_cam_ ].dims();
				v_px = viewports_[ active_cam_ ].dims_px();

				//ff = v[2] / v[3];

				active_cam_move_[0] = -(dx / v[2]) * v_px[2] * 2.0f * zoom_[ active_cam_ ];
				active_cam_move_[1] = (dy / v[3]) * v_px[3] * 2.0f * zoom_[ active_cam_ ];
				cams_[ active_cam_ ].Move(active_cam_move_, 1.0f);
				active_cam_move_[0] = 0.0f;
				active_cam_move_[1] = 0.0f;
				break;
			case RIGHT_TOP:
				rot_vec[0] = dy * 100.0f;
				rot_vec[1] = dx * 100.0f;
				cams_[ active_cam_ ].Rotate(rot_vec, 1.0f);
				break;
			}
		} else
		{
			if(!g_builder_brush->MovePoints(dx, dy, cams_[ active_cam_ ], viewports_[ active_cam_ ]))
			{
				if(!g_selection_frame->MovePoints(dx, dy, cams_[ active_cam_ ], viewports_[ active_cam_ ]))
				{
				}
			}
		}
		}

		dark_back_.UpdateSize(-1.0f + 17.0f/window_size_[0],
							   1.0f - 96.0f/window_size_[1],
							   2.0f - 32.0f/window_size_[0],
							   48.0f/window_size_[1],
							   window_size_);

		//menu_layout_.Resize(-1.0f, 1.0f-20.0f/window_size_[1], 2.0f, 0.4f, window_size_);
		menu_layout_.Resize(-1.0f + 2.0f*17.0f/window_size_[0], 1.0f - 85.0f/window_size_[1], 2.0f, 2.0f, window_size_);
		update_needed_ = false;

		return 0;
}

int EditorWindow::OnRelease(float x, float y) {
		
		if(MyBaseWindow::OnRelease(x, y) == -1)
		{
			return -1;
		}

		if(active_cam_ != -1)
		{
			//CheckBrush(x, y, cams_[ active_cam_ ], viewports_[ active_cam_ ]);

			cams_[ active_cam_ ].UpdatePlanes();
			last_active_cam_ = active_cam_;
			active_cam_ = -1;

		}

		right_panel_.Check(x, y);

		submit_input_btn_.Check(x, y);

		return 0;
	}

int EditorWindow::OnKeyPress(vector< unsigned char >& keys) {
		if(MyBaseWindow::OnKeyPress(keys) == -1)
		{
			return -1;
		}

		input_string_.Listen(keys);

		active_cam_move_[0] = 0.0f;
		active_cam_move_[1] = 0.0f;
		active_cam_move_[2] = 0.0f;

		for(auto key = keys.begin(); key != keys.end(); key++)
		{

			if(active_cam_ != -1 || last_active_cam_ != -1)
			{
				switch(*key)
				{
					case 'w':
						active_cam_move_[2] = -0.4f;
						break;
					case 's':
						active_cam_move_[2] = 0.4f;
						break;
					case 'a':
						active_cam_move_[0] = -0.4f;
						break;
					case 'd':
						active_cam_move_[0] = 0.4f;
						break;
					case SDLK_SPACE:
						if(maximized_view_ != -1)
						{
							maximized_view_ = -1;
						} else
						{
							if(active_cam_ != -1)
							{
								maximized_view_ = active_cam_;
							} else
							{
								maximized_view_ = last_active_cam_;
							}
						}

						update_needed_ = true;
						OnMove(0.0f, 0.0f);
						if(maximized_view_ != -1)
						{
							UpdateView(maximized_view_);
						}
						
						break;
				}
			}

		}

		return 0;
	}

int EditorWindow::OnWheelRot(bool dir) {

	if(last_active_cam_ == -1)
	{
		return 0;
	}

	if(dir)
	{
		zoom_[ last_active_cam_ ] *= 1.0f / 1.1f;
		cout << "in" << endl;
	} else
	{
		zoom_[ last_active_cam_ ] *= 1.1f;
		cout << "out" << endl;
	}

	const int* v_px = viewports_[last_active_cam_].dims_px();

	float hor = 0.5f * v_px[2] * zoom_[ last_active_cam_ ];
	float vert = 0.5f * v_px[3] * zoom_[ last_active_cam_ ];
	cams_[ last_active_cam_ ].Orthographic(-hor, hor, -vert, vert, 5.0f, 10000.0f);
	cams_[ last_active_cam_ ].UpdatePlanes();

	return 0;
}

void EditorWindow::ZoomIn() {

	zoom_[ last_active_cam_ ] *= 0.5f;

}

void EditorWindow::ZoomOut() {

	zoom_[ last_active_cam_ ] *= 2.0f;

}



void EditorWindow::DrawGrid(int view) {

		//const float* pos = cams_[ view ].world_position();


		float lim = -cams_[ view ].frustum_planes()[ RIGHT_PLANE ].d;
		float xx = static_cast<float>((static_cast<int>(cams_[ view ].frustum_planes()[ LEFT_PLANE ].d) / g_render_state.grid_size) * g_render_state.grid_size);

		glDisable(GL_DEPTH_TEST);

		glUniform3f(Renderer::render_state->current_program->uniform(COL_UNIFORM), 0.1f, 0.1f, 0.1f);
		glLineWidth(1.0f);

		glBegin(GL_LINES);

		switch(view) {
		case LEFT_TOP:
			while(xx > lim)
			{
				glVertex3f(xx, -1000.0, -100000.0);
				glVertex3f(xx, -1000.0, 100000.0);
				xx -= g_render_state.grid_size;
			}
			break;
		case LEFT_BOTTOM:
			while(xx > lim)
			{
				glVertex3f(-xx, -100000.0, -1000.0);
				glVertex3f(-xx, 100000.0, -1000.0);
				xx -= g_render_state.grid_size;
			}
			break;
		case RIGHT_BOTTOM:
			while(xx > lim)
			{
				glVertex3f(-1000.0, -100000.0, xx);
				glVertex3f(-1000.0, 100000.0, xx);
				xx -= g_render_state.grid_size;
			}
			break;

		}
		//glEnd();

		//glBegin(GL_LINES);

		lim = cams_[ view ].frustum_planes()[ TOP_PLANE ].d;
		xx =  static_cast<float>((static_cast<int>(-cams_[ view ].frustum_planes()[ BOTTOM_PLANE ].d) / g_render_state.grid_size) * g_render_state.grid_size);

		switch(view) {
		case LEFT_TOP:
			while(xx < lim)
			{
				glVertex3f(-100000.0, -1000.0, xx);
				glVertex3f(100000.0, -1000.0, xx);
				xx += g_render_state.grid_size;
			}
			break;
		case LEFT_BOTTOM:
			while(xx < lim)
			{
				glVertex3f(-100000.0, xx, -1000.0);
				glVertex3f(100000.0, xx, -1000.0);
				xx += g_render_state.grid_size;
			}
			break;
		case RIGHT_BOTTOM:
			while(xx < lim)
			{
				glVertex3f(-1000.0, xx, -100000.0);
				glVertex3f(-1000.0, xx, 100000.0);
				xx += g_render_state.grid_size;
			}
			break;
		}
		
		glEnd();
		
		glUniform3f(Renderer::render_state->current_program->uniform(COL_UNIFORM), 0.2f, 0.2f, 0.2f);
		xx =  static_cast<float>((static_cast<int>(-cams_[ view ].frustum_planes()[ BOTTOM_PLANE ].d) / (g_render_state.grid_size * 5)) * g_render_state.grid_size * 5);

		glBegin(GL_LINES);

		switch(view) {
		case LEFT_TOP:
			while(xx < lim)
			{
				glVertex3f(-100000.0, -1000.0, xx);
				glVertex3f(100000.0, -1000.0, xx);
				xx += g_render_state.grid_size * 5;
			}
			break;
		case LEFT_BOTTOM:
			while(xx < lim)
			{
				glVertex3f(-100000.0, xx, -1000.0);
				glVertex3f(100000.0, xx, -1000.0);
				xx += g_render_state.grid_size * 5;
			}
			break;
		case RIGHT_BOTTOM:
			while(xx < lim)
			{
				glVertex3f(-1000.0, xx, -100000.0);
				glVertex3f(-1000.0, xx, 100000.0);
				xx += g_render_state.grid_size * 5;
			}
			break;
		}

		lim = -cams_[ view ].frustum_planes()[ RIGHT_PLANE ].d;
		xx = static_cast<float>((static_cast<int>(cams_[ view ].frustum_planes()[ LEFT_PLANE ].d) / (g_render_state.grid_size * 5)) * g_render_state.grid_size * 5);

		switch(view) {
		case LEFT_TOP:
			while(xx > lim)
			{
				glVertex3f(xx, -1000.0, -100000.0);
				glVertex3f(xx, -1000.0, 100000.0);
				xx -= g_render_state.grid_size * 5;
			}
			break;
		case LEFT_BOTTOM:
			while(xx > lim)
			{
				glVertex3f(-xx, -100000.0, -1000.0);
				glVertex3f(-xx, 100000.0, -1000.0);
				xx -= g_render_state.grid_size * 5;
			}
			break;
		case RIGHT_BOTTOM:
			while(xx > lim)
			{
				glVertex3f(-1000.0, -100000.0, xx);
				glVertex3f(-1000.0, 100000.0, xx);
				xx -= g_render_state.grid_size * 5;
			}
			break;

		}

		glEnd();

		glUniform3f(Renderer::render_state->current_program->uniform(COL_UNIFORM), 0.2f, 0.2f, 0.2f);


	}

	void EditorWindow::Draw() {
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		MyBaseWindow::Draw();

		if(maximized_view_ == -1)
		{
			for(auto view = viewports_.begin(); view != viewports_.end(); view++)
			{
				(*view).Draw();
				view_names_[ view - viewports_.begin() ].Draw();
				if(view - viewports_.begin() == active_cam_ || view - viewports_.begin() == last_active_cam_)
				{
					const float* dims = (*view).dims();
					glLineWidth(3.0f);
					glBegin(GL_LINES);
						glVertex3f(dims[0], dims[1], 0.0f);
						glVertex3f(dims[0], dims[1] + dims[3], 0.0f);
						glVertex3f(dims[0], dims[1] + dims[3], 0.0f);
						glVertex3f(dims[0] + dims[2], dims[1] + dims[3], 0.0f);
						glVertex3f(dims[0] + dims[2], dims[1] + dims[3], 0.0f);
						glVertex3f(dims[0] + dims[2], dims[1], 0.0f);
						glVertex3f(dims[0] + dims[2], dims[1], 0.0f);
						glVertex3f(dims[0], dims[1], 0.0f);
					glEnd();
					glLineWidth(1.0f);
				}
			}
		} else
		{
			viewports_[ maximized_view_ ].Draw();
			view_names_[ maximized_view_ ].Draw();
		}

		right_panel_.Draw();

		input_string_.Draw();

		submit_input_btn_.Draw();

		dark_back_.Draw();
		menu_layout_.Draw();

		//file_dialog_.Draw();
		//if(file_dialog_.focused())
		//{
			//file_dialog_.MakeCurrent();
			//file_dialog_.Draw();
			//file_dialog_.Apply();
		//}

	}

	int EditorWindow::CreateBoxBrush() {
		RunCommand("CreateBoxBrushBB");
		return 0;
	}
	int EditorWindow::DecrGridStep() {
		g_render_state.grid_size /= 2;
		return 0;
	}
	int EditorWindow::IncrGridStep() {
		g_render_state.grid_size *= 2;
		return 0;
	}
	int EditorWindow::ClearSelection() {
		RunCommand("ClearSelection");
		return 0;
	}
	int EditorWindow::RotateCW() {

		int view = active_cam_;
		if(active_cam_ == -1)
		{
			view = last_active_cam_;
		}

		if(view != -1)
		{
			g_selection_frame->RotateFromView((180.0f/72.0f)*(g_render_state.grid_size/4), cams_[ view ]);
		}
		return 0;
	}
	int EditorWindow::RotateCCW() {

		int view = active_cam_;
		if(active_cam_ == -1)
		{
			view = last_active_cam_;
		}

		if(view != -1)
		{
			g_selection_frame->RotateFromView(-(180.0f/72.0f)*(g_render_state.grid_size/4), cams_[ view ]);
		}
		return 0;
	}
	int EditorWindow::EditModeToggle() {
		RunCommand("SetMode edit");
		return 0;
	}
	int EditorWindow::SelectModeOn() {
		RunCommand("SetMode select");
		return 0;
	}
	int EditorWindow::TextureModeOn() {
		RunCommand("SetMode texture");
		return 0;
	}
	int EditorWindow::SubmitInput() {
		string line = input_string_.GetLine(0);
		char lline[80];
		strcpy(lline, line.c_str());
		input_string_.DeleteLine(0);
		//input_string_->AddChar('z');
		RunCommand(lline);
		return 0;
	}
	int EditorWindow::DeleteSelected() {
		RunCommand("DeleteSelected");
		return 0;
	}
	int EditorWindow::CopySelected() {
		g_selection_frame->CopySelection();
		return 0;
	}

	int EditorWindow::NewFile(){
		lock_guard<mutex> render_lock(g_render_state.render_mtx);
		g_selection_frame->Clear();
		g_brushes.clear();
		g_static_meshes.clear();
		g_entities.clear();
		return 0;
	}

	int EditorWindow::OpenFile(){
		open_file_dlg_.Show();
		return 0;
	}

	int EditorWindow::SaveFile(){
		save_file_dlg_.Show();
		return 0;
	}

	int EditorWindow::Undo()
	{
		RunCommand("Undo");
		return 0;
	}

	int EditorWindow::Redo()
	{
		RunCommand("Redo");
		return 0;
	}


